﻿using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;

namespace JinYuan.ControlLib.UCHelper
{
    /// <summary>
    /// 主线程动画控件基类，不能时耗时操作，该定时器时UI线程计时器。耗时长对导致画面卡顿。
    /// </summary>
    [ToolboxItem(false)]
    [Description("动画控件基类")]
    public abstract class MainThreadAnimationControl : DpiControl
    {
        #region 字段

        /// <summary>
        /// 动画控件集合锁
        /// </summary>
        private static object animationcontrols_lock = new object();
        /// <summary>
        /// 动画控件集合
        /// </summary>
        private static List<MainThreadAnimationControl> animationcontrols = new List<MainThreadAnimationControl>();
        /// <summary>
        /// 动画定时器锁
        /// </summary>
        private static object timer_lock = new object();

        /// <summary>
        /// 定时器间隔
        /// </summary>
        private static Thread thread = null;
        /// <summary>
        /// 线程间隔
        /// </summary>
        private static int threadInterval = 100;


        private static CancellationTokenSource cts = new CancellationTokenSource();
        /// <summary>
        /// 停止线程
        /// </summary>
        private static ManualResetEvent stopEvent = new ManualResetEvent(false);

        //private static Timer timer = null;

        #endregion

        public MainThreadAnimationControl()
        {
            if (thread == null)
            {
                lock (timer_lock)
                {
                    thread = new Thread(() => ThreadFunction());
                    thread.IsBackground = true;
                    thread.Start();
                }
            }
        }

        #region 虚方法

        /// <summary>
        /// 动画控件动画中要处理的内容(不能时耗时操作，该定时器为UI线程计时器。耗时长对导致画面卡顿)
        /// </summary>
        /// <param name="interval">动画定时器间隔时间</param>
        protected virtual void Animationing(int interval)
        {

        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 定时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        internal static void ThreadFunction()
        {
            ArrayList indexArr = new ArrayList();
            while (true)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    return;
                }
                // stopEvent.WaitOne();

                for (int i = 0; i < animationcontrols.Count; i++)
                {
                    if (animationcontrols[i] != null)
                    {
                        animationcontrols[i].Animationing(threadInterval);
                    }
                    else
                    {
                        indexArr.Add(i);
                    }
                }

                if (indexArr.Count > 0)
                {
                    for (int i = 0; i < indexArr.Count; i++)
                    {
                        animationcontrols.RemoveAt((int)indexArr[i] - i);
                    }
                }
                if (animationcontrols.Count < 1)
                {
                    stopEvent.Set();
                }

                Thread.Sleep(threadInterval);
            }
        }

        /// <summary>
        /// 开始指定控件动画
        /// </summary>
        /// <param name="control"></param>
        internal static void AnimationStart(MainThreadAnimationControl control)
        {
            if (control == null)
                return;

            lock (animationcontrols_lock)
            {
                if (animationcontrols.IndexOf(control) < 0)
                {
                    animationcontrols.Add(control);
                }
            }
            stopEvent.Reset();
        }

        /// <summary>
        /// 停止指定控件动画
        /// </summary>
        /// <param name="control"></param>
        internal static void AnimationStop(MainThreadAnimationControl control)
        {
            if (control == null)
                return;

            lock (animationcontrols_lock)
            {
                animationcontrols.Remove(control);
            }
        }

        #endregion

    }
}
